#pragma once

#include <iostream>
#include <cstdio>
#include <string>
#include <set>

const int line_size = 1024;

class Command
{
public:
    Command()
    {
        _white_list.insert("ls");
        _white_list.insert("pwd");
        _white_list.insert("ls -l");
        _white_list.insert("ll");
        _white_list.insert("ls -a -l");
        _white_list.insert("who");
        _white_list.insert("whoami");
    }

    bool SafeCheck(const std::string& cmdstr)
    {
        auto iter = _white_list.find(cmdstr);
        return iter != _white_list.end();
    }

    std::string Execute(std::string cmdstr)
    {
        // 1.pipe
        // 2.fork + dup2(pipe[1], 1) + exec*
        // 3.父进程读取
        if (!SafeCheck(cmdstr)) return cmdstr + " 不支持！";

        FILE* fp = popen(cmdstr.c_str(), "r");
        if (fp == nullptr)
        {
            return "Failed";
        }
        std::string result;
        char buffer[line_size];
        while (true)
        {
            char* p = ::fgets(buffer, sizeof(buffer), fp);
            if (p == nullptr) break;
            result += buffer;
        }
        pclose(fp);
        return result.empty() ? "Done" : result;
    }
private:
    std::set<std::string> _white_list;
};